package com.gyj.activiti.controller;

import com.gyj.activiti.config.RestResult;
import com.gyj.activiti.dao.mapper.ApplyInfoMapper;
import com.gyj.activiti.model.ApplyInfo;
import com.gyj.activiti.model.ApplyInfoExample;
import com.gyj.activiti.service.ActivitiService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Gao
 * @date 2019/4/4
 */
@Api(tags = "工作流请假流程相关接口")
@RestController
@RequestMapping("/activitiApply")
public class ActivitiApplyController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ActivitiService activitiService;

    @Autowired
    private ApplyInfoMapper applyInfoMapper;

    /**
     * 获取默认流程引擎实例，会自动读取activiti.cfg.xml文件， 默认放在resource目录下
     */
    private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    private final Logger log = LoggerFactory.getLogger(ActivitiApplyController.class);

    @ApiOperation(value = "提交请假申请")
    @GetMapping("/commitLeaveApply")
    public RestResult<String> commitLeaveApply(@ApiParam("请假天数") @RequestParam(name = "days") byte days,
                                               @ApiParam("请假原因") @RequestParam(name = "reason") String reason,
                                               @ApiParam("申请人") @RequestParam(name = "applyer") String applyer,
                                               @ApiParam("流程模板，选填，默认是111.bpmn") @RequestParam(name = "flowModel", required = false) String flowModel) {
        String curFlowModel = null;
        if (flowModel == null) {
            curFlowModel = "111.bpmn";
        } else {
            curFlowModel = flowModel + ".bpmn";
        }
        repositoryService.createDeployment()
                .addClasspathResource(curFlowModel).name("studentForLeave").deploy();
        //采用key来启动流程定义并设置流程变量，返回流程实例
        Map<String, Object> map = new HashMap<>(5);
        map.put("user111", applyer);
        //采用key来启动流程定义并设置流程变量，返回流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess111", map);
        //获取流程Id
        String processId = processInstance.getId();
        Integer integer = activitiService.insertApply(processId, days, reason, applyer);
        //查看学生的任务列表，这里需要拿student来查询，key-value需要拿value来获取任务
        List<Task> list = taskService.createTaskQuery().taskAssignee(applyer).processInstanceId(processId).list();
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                System.out.println("任务ID：" + task.getId());
                System.out.println("任务的办理人：" + task.getAssignee());
                System.out.println("任务名称：" + task.getName());
                System.out.println("流程实例ID：" + task.getProcessInstanceId());
                Map<String, Object> variables1 = new HashMap<>(5);
                variables1.put("days", days);
                if (integer > 0) {
                    taskService.complete(task.getId(), variables1);
                    return RestResult.ok("申请成功！");
                }
            }
        }

        return RestResult.ok("申请失败！");
    }

    @ApiOperation(value = "领导审批根据流程Id")
    @GetMapping("/masterApproveByProcessId")
    public RestResult<String> masterApply(@ApiParam("流程Id") @RequestParam(name = "processId") String processId,
                                          @ApiParam("审批结果") @RequestParam(name = "comment") String comment,
                                          @ApiParam("审批结果：0不通过，1通过") @RequestParam(name = "approveResult") Byte approveResult) {
        //查看任务列表
        List<Task> masterList = taskService.createTaskQuery().processInstanceId(processId).list();
        if (masterList.size() == 0 || masterList.isEmpty()) {
            return RestResult.ok("审批列表为空！");
        }

        for (Task task : masterList) {
            System.out.println("任务ID：" + task.getId());
            System.out.println("任务的办理人：" + task.getAssignee());
            System.out.println("任务名称：" + task.getName());
            System.out.println("流程实例ID：" + task.getProcessInstanceId());
            Integer integer = activitiService.insertApprove(task, processId, comment, approveResult);
            //更新学生申请结果
            ApplyInfoExample applyInfoExample = new ApplyInfoExample();
            applyInfoExample.getCriteria().andProcessinstanceidEqualTo(processId);
            List<ApplyInfo> applyInfoList = applyInfoMapper.selectByExample(applyInfoExample);
            if (applyInfoList != null && applyInfoList.size() > 0) {
                ApplyInfo applyInfo = applyInfoList.get(0);
                applyInfo.setProcessstatus(approveResult);
                int i = applyInfoMapper.updateByExample(applyInfo, applyInfoExample);
                if (integer > 0 && i > 0) {
                    //根据任务流程ID完成审批任务
                    Map<String, Object> map = new HashMap<>(2);
                    map.put("auditResult", approveResult);
                    taskService.complete(task.getId(), map);
                    if (approveResult == 1) {
                        return RestResult.ok("审批成功！");
                    } else {
                        return RestResult.ok("流程结束！");
                    }
                }
            }
        }

        return RestResult.ok("审批失败！");
    }

    @ApiOperation(value = "获取审批列表")
    @GetMapping("/getApproveList")
    public RestResult<List<ApplyInfo>> getApproveList(@RequestParam(name = "master") String master) {
        //List<String> assignId = new ArrayList<>(1);
        //assignId.add("master_2");
        //查看当前正在执行的任务列表
        List<Task> masterList = taskService.createTaskQuery().taskAssignee(master).list();
        if (masterList != null && masterList.size() > 0) {
            int size = masterList.size();
            List<String> processIdList = new ArrayList<>(size);
            for (Task task : masterList) {
                processIdList.add(task.getProcessInstanceId());
            }
            if (!processIdList.isEmpty()) {
                ApplyInfoExample applyInfoExample = new ApplyInfoExample();
                applyInfoExample.getCriteria().andProcessinstanceidIn(processIdList);
                List<ApplyInfo> applyInfoList = applyInfoMapper.selectByExample(applyInfoExample);
                return RestResult.ok(applyInfoList);
            }
        }

        return RestResult.ok(null);
    }

    @ApiOperation(value = "HR根据流程Id结束流程")
    @GetMapping(value = "/commitFlowByProcessId")
    public RestResult<String> commitFlowByProcessId(@ApiParam("流程Id") @RequestParam(name = "processId") String processId) {
        //查看任务列表
        List<Task> masterList = taskService.createTaskQuery().processInstanceId(processId).list();
        if (masterList.size() == 0 || masterList.isEmpty()) {
            return RestResult.ok("审批列表为空！");
        }

        for (Task task : masterList) {
            System.out.println("任务ID：" + task.getId());
            System.out.println("任务的办理人：" + task.getAssignee());
            System.out.println("任务名称：" + task.getName());
            System.out.println("流程实例ID：" + task.getProcessInstanceId());
            taskService.complete(task.getId());
        }

        return RestResult.ok("流程结束！");
    }

    @ApiOperation(value = "主任撤销申请根据流程Id")
    @GetMapping(value = "/masterRevokeApply")
    public RestResult<String> masterRevokeApply(@ApiParam("流程Id") @RequestParam(name = "processId") String processId) {

        return RestResult.ok("撤销申请！");
    }

    @ApiOperation(value = "获取全部历史审批列表(可以获取已经完成或者未完成的任务列表)")
    @GetMapping("/getAllToApproveAndApprovedList")
    public RestResult<List<ApplyInfo>> getAllToApproveAndApprovedList(@RequestParam(name = "master") String master) {
        // 获得历史任务列表(可以获取已经完成或者未完成的任务列表)
        List<HistoricTaskInstance> masterList = processEngine.getHistoryService()
                .createHistoricTaskInstanceQuery().taskAssignee(master).finished().list();
        if (masterList != null && masterList.size() > 0) {
            for (HistoricTaskInstance hpi : masterList) {
                System.out.println("流程定义ID：" + hpi.getProcessDefinitionId());
                System.out.println("流程实例ID：" + hpi.getId());
                System.out.println("开始时间：" + hpi.getStartTime());
                //System.out.println("结束时间：" + hpi.getEndTime());
                //System.out.println("流程持续时间：" + hpi.getDurationInMillis());
            }
        }
        return RestResult.ok(null);
    }

    /**
     * 查看流程图的接口，用swagger请求会请求两次，直接在网页请求以及用postman的时候只会请求一次，也能返回结果
     */
    @ApiOperation(value = "根据流程ID查看当前流程节点")
    @GetMapping(value = "/showCurrentFlowImage")
    public void getCurrentDiagram(@ApiParam("流程Id") @RequestParam(name = "processId") String processId,
                                 HttpServletResponse response) throws IOException {
        InputStream inputStream = null;
        OutputStream out = null;
        try {
            inputStream = activitiService.getCurrentDiagram(processId);
            if (inputStream == null) {
                return;
            }
            response.setContentType("image/png");
            BufferedImage image = ImageIO.read(inputStream);
            out = response.getOutputStream();
            ImageIO.write(image, "png", out);
            inputStream.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation(value = "根据流程ID查看历史节点流程")
    @GetMapping(value = "/showHistoryFlowNodeImage")
    public void showHistoryFlowNodeImage(@ApiParam("流程Id") @RequestParam(name = "processId") String processId,
                                        HttpServletResponse response) {
        try {
            InputStream inputStream = activitiService.showHistoryFlowNodeImage(processId);
            if (inputStream == null) {
                return;
            }
            response.setContentType("image/png");
            BufferedImage image = ImageIO.read(inputStream);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "png", out);
            inputStream.close();
            out.close();
        } catch (Exception e) {
            log.error("查看流程图失败");
        }
    }

    @ApiOperation(value = "根据流程ID查看历史节点及连接线流程")
    @GetMapping(value = "/showHistoryFlowNodeAndLineImage")
    public void showHistoryFlowNodeAndLineImage(@ApiParam("流程Id") @RequestParam(name = "processId") String processId,
                                     HttpServletResponse response) {
        try {
            InputStream inputStream = activitiService.showHistoryFlowNodeAndLineImage(processId);
            if (inputStream == null) {
                return;
            }
            response.setContentType("image/png");
            BufferedImage image = ImageIO.read(inputStream);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "png", out);
            inputStream.close();
            out.close();
        } catch (Exception e) {
            log.error("查看流程图失败");
        }
    }

}
